#include<stdio.h>
#include<stdbool.h>
#define Size 10

// 初始化函数 : 用于对操作对象的初始状态赋值
void InitBoard(char (*Board)[Size])
{
    for(int i = 0; i < Size; i++)
    {
        for(int j = 0; j < Size; j++)
        {
            Board[i][j] = '-';   // 每个位置初始化为空格
        }
    }
}

// 打印棋盘
void PrintBoard(char (*Board)[Size])
{
    printf("   \\");
    for(int i = 0; i < Size; i++)
    {
        printf("%4d",i+1);
    }
    printf("\n");
    for(int i = 0; i < Size; i++)
    {
        printf("%4d",i+1);
        for(int j = 0; j < Size; j++)
        {
            printf("%4c", Board[i][j]);
        }
        printf("\n");
    }
}

// 下棋
bool MakeMove(char (*Board)[Size], int row, int col, char player)
{
    // 非法位置
    if(row < 0 || row >= Size || col < 0 || col >= Size)
    {
        printf("下棋位置错误，请重新输入！\n");
        return false;
    }
    // 下棋位置有棋子
    if(Board[row][col] != '-')
    {
        printf("该位置已有棋子，请重新输入！\n");
        return false;
    }
    Board[row][col] = player;
    return true;
}

// 判断位置是否合法
bool IsValidPlace(char (*Board)[Size], int row, int col)
{
    // 非法位置
    if(row < 0 || row >= Size || col < 0 || col >= Size)
    {
        return false;
    }
    return true;
}

// 判断是否获胜
bool CheckIsWin(char (*Board)[Size], int row, int col, char player)
{
    int direction[4][2] = 
    {
        {1,0}, // 垂直
        {1,1}, // 主对角线
        {0,1}, // 水平
        {-1,1} // 副对角线
    };

    // 遍历四个方向数棋子数量
    for(int i = 0; i < 4; i++)
    {
        int count = 1;
        // 正方向
        int drow = row + direction[i][0];
        int dcol = col + direction[i][1];
        while(IsValidPlace(Board, drow, dcol) && Board[drow][dcol] == player)
        {
            count++;
            if(count >= 5)
                return true;
            drow += direction[i][0];
            dcol += direction[i][1];
        }

        // 反方向
        drow = row - direction[i][0];
        dcol = col - direction[i][1];
        while(IsValidPlace(Board, drow, dcol) && Board[drow][dcol] == player)
        {
            count++;
            if(count >= 5)
                return true;
            drow -= direction[i][0];
            dcol -= direction[i][1];
        }


    }
    return false;
}

// 判断能否构成一条线
bool CheckIsCount(char (*Board)[Size], int row, int col, char player, int number)
{
    int direction[4][2] = 
    {
        {1,0},
        {1,1},
        {0,1},
        {-1,1}
    };

    for(int i = 0; i < 4; i++)
    {
        int count = 1;
        // 正方向
        int drow = row + direction[i][0];
        int dcol = col + direction[i][1];
        while(IsValidPlace(Board, drow, dcol) && Board[drow][dcol] == player)
        {
            count++;
            if(count >= number)
                return true;
            drow += direction[i][0];
            dcol += direction[i][1];
        }

        // 反方向
        drow = row - direction[i][0];
        dcol = col - direction[i][1];
        while(IsValidPlace(Board, drow, dcol) && Board[drow][dcol] == player)
        {
            count++;
            if(count >= number) // 修正此处
                return true;
            drow -= direction[i][0];
            dcol -= direction[i][1];
        }
    }
    return false;
}

// 判断是否平局
bool CheckIsDraw(char (*Board)[Size])
{
    for(int i = 0; i < Size; i++)
    {
        for(int j = 0; j < Size; j++)
        {
            if(Board[i][j] == '-')
                return false;
        }
    }
    return true;
}

// 修改后的 AIMakeMove 函数，使其返回 AI 的移动位置
bool AIMakeMove(char (*Board)[Size], int* moveRow, int* moveCol)
{
    // 优先取胜策略
    for(int i = 0; i < Size; i++)
    {
        for(int j = 0; j < Size; j++)
        {
            if(Board[i][j] == '-')
            {
                Board[i][j] = 'O';
                if(CheckIsWin(Board, i, j, 'O'))
                {
                    *moveRow = i;
                    *moveCol = j;
                    return true;
                }
                Board[i][j] = '-';
            }
        }
    }

    // 阻止玩家赢
    for(int k = 5; k >= 1; k--)
    {
        for(int i = 0; i < Size; i++)
        {
            for(int j = 0; j < Size; j++)
            {
                if(Board[i][j] == '-')
                {
                    Board[i][j] = 'X';
                    if(CheckIsCount(Board, i, j, 'X', k))
                    {
                        Board[i][j] = 'O';
                        *moveRow = i;
                        *moveCol = j;
                        return true;
                    }
                    Board[i][j] = '-';
                }
            }
        }
    }

    // 后备措施：选择第一个空位
    for(int i = 0; i < Size; i++)
    {
        for(int j = 0; j < Size; j++)
        {
            if(Board[i][j] == '-')
            {
                Board[i][j] = 'O';
                *moveRow = i;
                *moveCol = j;
                return true;
            }
        }
    }

    return false; // 如果没有可下的位置
}

int main()
{
    char Board[Size][Size] = {0};
    InitBoard(Board);
    char player = 'X';
    int row = 0, col = 0;
    int lastRow = -1, lastCol = -1; // 记录上一次的移动位置

    while(1)
    {
        PrintBoard(Board);

        if(player == 'X')
        {
            printf("请|%c|选手下棋 (输入行 列,1-%d):\n", player, Size);
            if(scanf("%d %d", &row, &col) != 2)
            {
                printf("输入无效，请输入两个整数!!!\n");
                // 清理输入缓冲区
                while (getchar() != '\n');
                continue;
            }
            if(row < 1 || row > Size || col < 1 || col > Size)
            {
                printf("输入范围错误,请输入1到%d之间的数字!!!\n", Size);
                continue;
            }
            if(MakeMove(Board, row-1, col-1, player) == false)
            {
                continue;
            }
            lastRow = row - 1;
            lastCol = col - 1;
        }
        else
        {
            printf("AI正在下棋......\n");
            if(AIMakeMove(Board, &lastRow, &lastCol) == false)
            {
                printf("AI无法下棋,游戏结束。\n");
                break;
            }
        }

        if(lastRow != -1 && lastCol != -1) // 确保有移动记录
        {
            if(CheckIsWin(Board, lastRow, lastCol, player) == true)
            {
                PrintBoard(Board);
                printf("恭喜|%c|选手获胜！\n", player);
                break;
            }
        }

        if(CheckIsDraw(Board))
        {
            PrintBoard(Board);
            printf("平局！\n");
            break;
        }

        // 换边
        player = (player == 'X') ? 'O' : 'X';
    }

    return 0;
}